package com.hanter.android.radwidget;

import android.os.Bundle;
import android.util.Log;
import android.view.View;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;


public abstract class LazyFragment extends Fragment {

    protected static final String TAG = "LazyFragment";

    private static final boolean DEBUG = false;

    public static final String ARG_USE_HINT = "useHint";

    private boolean useUserVisibleHint;
    private boolean firstVisible = true;
    private boolean firstInvisible = true;
    private boolean prepared;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        if (savedInstanceState == null) {
            if (getArguments() != null) {
                useUserVisibleHint = getArguments().getBoolean(ARG_USE_HINT);
            }
        } else {
            useUserVisibleHint = savedInstanceState.getBoolean(ARG_USE_HINT);
        }
    }

    @Override
    public void onSaveInstanceState(@NonNull Bundle outState) {
        outState.putBoolean(ARG_USE_HINT, useUserVisibleHint);
        super.onSaveInstanceState(outState);
    }

    @SuppressWarnings("deprecation")
    @Override
    public void setUserVisibleHint(boolean isVisibleToUser) {
        super.setUserVisibleHint(isVisibleToUser);

        if (!useUserVisibleHint)
            return;

        if (prepared) {
            if (isVisibleToUser) {
                onSetUserVisible();
            } else {
                onSetUserInvisible();
            }
        }
    }

    @Override
    public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);
        log("onViewCreated");
    }

    @Override
    public void onActivityCreated(@Nullable Bundle savedInstanceState) {
        log("onActivityCreated");

        super.onActivityCreated(savedInstanceState);

        prepared = true;

        //noinspection deprecation
        if (useUserVisibleHint && getUserVisibleHint()) {
            onSetUserVisible();
        }
    }

    @Override
    public void onHiddenChanged(boolean hidden) {
        super.onHiddenChanged(hidden);
        log("onHiddenChanged: "  + hidden);
    }

    @SuppressWarnings("deprecation")
    @Override
    public void onResume() {
        super.onResume();
        log("onResume");
        if (!useUserVisibleHint || getUserVisibleHint()) {
            onSetUserVisible();
        }
    }

    @SuppressWarnings("deprecation")
    @Override
    public void onPause() {
        log("onPause");
        if (!useUserVisibleHint || getUserVisibleHint()) {
            onSetUserInvisible();
        }
        super.onPause();
    }

    @Override
    public void onDestroyView() {
        log("onDestroyView");
        prepared = false;
        super.onDestroyView();
    }

    private void onSetUserVisible() {
        if (firstVisible) {
            firstVisible = false;
            onFirstUserVisible();
        } else {
            onUserVisible();
        }
    }

    private void onSetUserInvisible() {
        if (firstInvisible) {
            firstInvisible = false;
            onFirstUserInvisible();
        } else {
            onUserInvisible();
        }
    }

    private void log(String str) {
        if (DEBUG)
            Log.d(TAG, "fragment: " + getTag() + " " + str);
    }

    protected abstract void onFirstUserVisible();

    protected abstract void onUserVisible();

    protected abstract void onFirstUserInvisible();

    protected abstract void onUserInvisible();
}